package com.sites.cds.common.directive;

import com.jfinal.aop.Aop;
import com.jfinal.template.Directive;
import com.jfinal.template.Env;
import com.jfinal.template.TemplateException;
import com.jfinal.template.expr.ast.Expr;
import com.jfinal.template.expr.ast.ExprList;
import com.jfinal.template.io.Writer;
import com.jfinal.template.stat.ParseException;
import com.jfinal.template.stat.Scope;
import com.sites.common.model.Article;

/**
 * 下一篇文章自定义指令
 * 和ArticlePriorDirective几乎一样，为了使用的时候更好理解，独立写了相关指令
 * 
 * #an(articleId, columnId, paraName)
 * 		#(paraName.title??)
 * #end
 * 
 * @author zyg
 * 2021年1月10日 下午9:52:36
 */
public class ArticleNextDirective extends Directive {


	private Expr articleIdExpr;//指令的第一个参数：文章id
	private Expr columnIdExpr;//指令的第二个参数：文章所属栏目id
	private Expr paraNameExpr;//指令的第三个参数：放置数据的参数名
	
	private int articleId;
	private int columnId;
	private String paraName = "an";
	private int paraNums;
	
	private DirectiveService srv = Aop.get(DirectiveService.class);
	
	@Override
	public void setExprList(ExprList exprList) {
		paraNums = exprList.length();
		//指令参数个数校验
		if(paraNums<2 || paraNums>3){
			throw new ParseException("Wrong number parameter of #an directive, two or three parameters allowed", location);
		}
		articleIdExpr = exprList.getExpr(0);
		columnIdExpr = exprList.getExpr(1);
		if(paraNums==3){
			paraNameExpr = exprList.getExpr(2);
		}
	}
	
	@Override
	public void exec(Env env, Scope scope, Writer writer) {
		Object articleIdObject = articleIdExpr.eval(scope);
		if(articleIdObject instanceof Integer){
			articleId = (Integer) articleIdObject;
		} else {
			throw new TemplateException("The first parameter of #an directive must be Integer type", location);
		}
		
		Object columnIdObject = columnIdExpr.eval(scope);
		if(columnIdObject instanceof Integer){
			columnId = (Integer) columnIdObject;
		} else {
			throw new TemplateException("The second parameter of #an directive must be Integer type", location);
		}
		
		if(paraNums==3){
			Object paraNameObject = paraNameExpr.eval(scope);
			if(paraNameObject instanceof String){
				paraName = (String)paraNameObject;
			} else {
				throw new TemplateException("The third parameter of #an directive must be String type", location);
			}
		}
		
		//数据库查询上一篇文章
		Article article = srv.getArtPriorNext(articleId, columnId, "next");
		scope.set(paraName, article);
		stat.exec(env, scope, writer);
	}
	
	@Override
	public boolean hasEnd() {
		return true;
	}

}
